#include "str.h"

str::str(QObject *parent) : QObject(parent)
{

}

qint8 str::char2Hex(char ch)
{
    if(ch >= '0' && ch <= '9')
        return (ch - '0');
    else if(ch >= 'A' && ch <= 'F')
        return (ch - 'A' + 10);
    else if(ch >= 'a' && ch <= 'f')
        return (ch - 'a' + 10);
    else
        return 0;
}

bool str::string2Hex(const QString &str, QByteArray *baHex)
{
    qint32 len = str.length();
    qint32 i = 0;
    baHex->clear();
    if(len % 2)
    {
        char data = char2Hex(str.at(0).toLatin1());
        baHex->append(data);
        i++;
    }
    for(; i < len; i += 2)
    {
        char data = 0;
        data = char2Hex(str.at(i).toLatin1());
        data <<= 4;
        data |= char2Hex(str.at(i+1).toLatin1());
        baHex->append(data);
    }
    return true;
}

void str::hex2Ascii(const QByteArray &hex, QByteArray *ascii)
{
    qint32 len = hex.length();
    qint32 i;
    ascii->clear();
    for(i = 0; i < len; i++)
    {
        qint8 data = (hex.at(i) & 0xF0) >> 4;
        if(data >= 0 && data <= 9)
            ascii->append(data + '0');
        else
            ascii->append(data - 0x0A + 'A');

        data = (hex.at(i) & 0x0F);
        if(data >= 0 && data <= 9)
            ascii->append(data + '0');
        else
            ascii->append(data - 0x0A + 'A');
    }
}

void str::hex2String(const QByteArray &hex, QString *str)
{
    qint32 len = hex.length();
    qint32 i;
    str->clear();
    for(i = 0; i < len; i++)
    {
        qint8 data = (hex.at(i) & 0xF0) >> 4;
        if(data >= 0 && data <= 9)
            str->append(data + '0');
        else
            str->append(data - 0x0A + 'A');

        data = (hex.at(i) & 0x0F);
        if(data >= 0 && data <= 9)
            str->append(data + '0');
        else
            str->append(data - 0x0A + 'A');

        str->append(' ');
    }
}

QString str::stringTransfer(const QString &str)
{
    qint32 len = str.length();
    QString string;
    string.clear();
    for(qint32 i = 0; i < len; i++)
    {
        if(str.at(i) == QChar('\\'))
        {
            switch(str.at(i+1).toLatin1())
            {
            case 'r':
                string.append(0x0D);
                i++;
                break;
            case 'n':
                string.append(0x0A);
                i++;
                break;
            case 't':
                string.append(0x09);
                i++;
                break;
            case '\\':
                string.append(92);
                i++;
                break;
            default:
                string.append(str.at(i));
                break;
            }
        }
        else
        {
            string.append(str.at(i));
        }
    }
    return string;
}

bool str::byte32Swap(QByteArray &ba)
{
    if (ba.size() == 4)
    {
        char *p = ba.data();
        char temp = p[0];
        p[0] = p[3];
        p[3] = temp;
        temp = p[1];
        p[1] = p[2];
        p[2] = temp;

        return true;
    }
    return false;
}

void str::addCRC16(uint8_t *buffer, uint16_t n, uint16_t *pcrc)
{
    uint16_t i, j, carry_flag, a;

    for (i = 0; i < n; i++)
    {
        *pcrc = *pcrc ^ buffer[i];
        for (j = 0; j < 8; j++)
        {
            a = *pcrc;
            carry_flag = a & 0x0001;
            *pcrc = *pcrc >> 1;
            if (carry_flag == 1)
                *pcrc = *pcrc ^ 0xa001;
        }
    }

}

uint8_t str::checkCRC16(uint8_t *buffer, uint16_t n)
{
    uint16_t crc0 = 0x0;
    uint16_t crc1 = 0xffff;

    if (n >= 2)
    {
        crc0 = (((uint16_t)(buffer[n - 2]) << 8) | (uint16_t)(buffer[n - 1]));
        addCRC16(buffer,n - 2,&crc1);
    }

    return (crc0 == crc1);
}
